package cn.pconline.autoclub.web.app;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.StatusLine;
import org.apache.http.util.EntityUtils;
import org.gelivable.dao.GeliDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.pconline.autoclub.config.SystemConfig;
import cn.pconline.autoclub.entity.Activity;
import cn.pconline.autoclub.entity.AppBanner;
import cn.pconline.autoclub.entity.CheckIn;
import cn.pconline.autoclub.entity.Club;
import cn.pconline.autoclub.entity.ClubAddress;
import cn.pconline.autoclub.entity.ClubDraft;
import cn.pconline.autoclub.entity.ClubForum;
import cn.pconline.autoclub.entity.ClubLevel;
import cn.pconline.autoclub.entity.ClubMember;
import cn.pconline.autoclub.entity.ClubNotice;
import cn.pconline.autoclub.entity.MemberApplication;
import cn.pconline.autoclub.entity.PromotionPublish;
import cn.pconline.autoclub.entity.Theme;
import cn.pconline.autoclub.entity.User;
import cn.pconline.autoclub.service.ActivityService;
import cn.pconline.autoclub.service.AlbumService;
import cn.pconline.autoclub.service.AppBannerService;
import cn.pconline.autoclub.service.CensorNoticeService;
import cn.pconline.autoclub.service.CheckInService;
import cn.pconline.autoclub.service.ClubDraftService;
import cn.pconline.autoclub.service.ClubLevelService;
import cn.pconline.autoclub.service.ClubPvService;
import cn.pconline.autoclub.service.ClubService;
import cn.pconline.autoclub.service.CommentService;
import cn.pconline.autoclub.service.DynaService;
import cn.pconline.autoclub.service.IntfService;
import cn.pconline.autoclub.service.MemberService;
import cn.pconline.autoclub.service.MessageService;
import cn.pconline.autoclub.service.PetrolService;
import cn.pconline.autoclub.service.PromotionService;
import cn.pconline.autoclub.service.ThemeService;
import cn.pconline.autoclub.service.TopicService;
import cn.pconline.autoclub.service.UserForumService;
import cn.pconline.autoclub.service.UserService;
import cn.pconline.autoclub.util.AppUtils;
import cn.pconline.autoclub.util.DateUtils;
import cn.pconline.autoclub.util.EncodeUtils;
import cn.pconline.autoclub.util.McUtils;
import cn.pconline.autoclub.util.Pager;
import cn.pconline.autoclub.util.Regex;
import cn.pconline.autoclub.util.RegionUtil;
import cn.pconline.autoclub.util.StringUtil;
import cn.pconline.autoclub.util.WebUtils;
import cn.pconline.autoclub.util.app.AppControllerStatic;
import cn.pconline.autoclub.util.dyna.AbstractDyna;
import cn.pconline.autoclub.web.UserAuth;
import cn.pconline.r.client.EntityBuilder;
import cn.pconline.r.client.ResponseExtractor;
import cn.pconline.r.client.SimpleHttpTemplate;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.danga.MemCached.MemCachedClient;

/**
 * http://trac.pc.com.cn/iphone/wiki/pcauto_club_2.0.0/api
 *
 * @author chenchongqi
 */
@Controller
@RequestMapping(value = "/appapi")
public class AppClubController {
    
    @Autowired
    private UserService userService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private ClubService clubService;
    @Autowired
    private ActivityService activityService;
    @Autowired
    private ClubLevelService clubLevelService;
    @Autowired
    private CommentService commentService;
    @Autowired
    private AlbumService albumService;
    @Autowired
    private TopicService topicService;
    @Autowired
    private PetrolService petrolService;
    @Autowired
    private PromotionService promotionService;
    @Autowired
    private SystemConfig systemConfig;
    @Autowired
    private CheckInService checkInService;
    @Autowired
    private IntfService intfService;
    @Autowired
    private UserAuth userAuth;
    @Autowired
    private MessageService messageService;
    @Autowired
    private ThemeService themeService;
    @Autowired
    private SimpleHttpTemplate simpleHttpTemplate;
    @Autowired
    private GeliDao geliDao;
    @Autowired
    private CensorNoticeService censorNoticeService;
    @Autowired
    private DynaService dynaService;
    @Autowired
    private ClubDraftService clubDraftService;
    @Autowired
    private MemCachedClient mcc;
    @Autowired
    private ClubPvService clubPvService;
    @Autowired
    private AppBannerService appBannerService;
    @Autowired
    private UserForumService userForumService;

    private static final Logger log = LoggerFactory.getLogger(AppClubController.class);
    /**个人中心 性别  1-男**/
    private static final int MALE = 1;
    /**个人中心 性别  2-女**/
    private final static int FEMALE = 2;

    /**
     * 2.1 车友会详情接口
     * 原接口url:http://车友会域名/util/clubQrCode.jsp?clubId=车友会id
     	整合到:2.4车友会搜索接口
     	根据车友会ID返回车友会详情
     	获取车友会二维码接口
     */
    @RequestMapping(value = "/1.0/club/qrcode.do", method = RequestMethod.GET)
    public String getClubQRCode(HttpServletRequest request, Model model, HttpServletResponse resp) {
        long clubId = AppControllerStatic.paramClubId(request);
        return "/util/clubQrCode.jsp?clubId=" + clubId;
    }
    
    /**
     * 2.2车友会信息与已加入的车友会权限列表接口
     	原接口URL:/club/getJoinedClubList.do
     	说明:获取车友会信息与已加入的车友会权限列表
     */

    @ResponseBody
    @RequestMapping(value = "/1.0/club/getUserClubs.do", method = RequestMethod.GET)
    public void getUserClubs(HttpServletRequest req, HttpServletResponse resp) {
        WebUtils.setEncoding4App(req, resp);
        JSONObject json = new JSONObject();
        long uid = AppControllerStatic.paramUserId(req);
        int xssEncode = WebUtils.paramInt(req, AppControllerStatic.APP_API_PARA_XSSENCODE, 1);
        String callback = AppControllerStatic.paramCallback(req);

        JSONObject jsonObject = new JSONObject();

        User user;
        ClubMember cm = null;
        if (uid == 0) {
            AppUtils.setNoLoginCode(json);
            return;
        } else {
            user = userService.findUser(uid);
            if (user != null) {
                cm = memberService.findClubMemberByUserId(uid);
            }
            if (user == null || cm == null) {
                AppControllerStatic.printErrorMsg(resp, "用户没有加入车友会", jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
                return;
            }
        }

        if (user != null && cm != null) {
            Club club = clubService.getClub(cm.getClubId());
            ClubAddress clubAddr = clubService.getAddress(cm.getClubId());
            ClubNotice notice = clubService.getNotice(cm.getClubId());
            Activity activity = activityService.getLatestActivityByClub(cm.getClubId());
            ClubLevel level = clubLevelService.getById(club.getLevelId());

            JSONObject clubObject =
                    xssEncode > 0 ? club.toJsonEncodeHTML() : club.toJson();

            JSONObject clubAddrObject =
                    xssEncode > 0 ? clubAddr.toJsonEncodeHTML() : clubAddr.toJson();

            JSONObject userObject =
                    xssEncode > 0 ? user.toJsonEncodeHTML() : user.toJson();

            JSONObject noticeObject =
                    xssEncode > 0 ? notice.toJsonEncodeHTML() : notice.toJson();

            JSONObject activityObject =
                    xssEncode > 0 ? activity.toJsonEncodeHTML() : activity.toJson();

            JSONObject levelObject =
                    xssEncode > 0 ? level.toJsonEncodeHTML() : level.toJson();

            clubObject.put("clubAddress", clubAddrObject);
            clubObject.put("clubMember", cm.toJson());
            clubObject.put("user", userObject);
            clubObject.put("clubNotice", noticeObject);
            clubObject.put("lastActivity", activityObject);
            clubObject.put("clubLevel", levelObject);
            clubObject.put("commentSum", commentService.countByClubId(club.getClubId()));
            clubObject.put("albumSum", albumService.countAlbumByClubId(club.getClubId()));
            clubObject.put("photoSum", albumService.countPhotoByClubId(club.getClubId()));
            clubObject.put("topicSum", topicService.countByClubId(club.getClubId()));
            clubObject.put("activitySum", activityService.countActivityByClubId(club.getClubId()));
            clubObject.put("totalPetrol", petrolService.getValidPetrol(club.getClubId()).getTotalPetrol());

            AppControllerStatic.printSuccessMsg(resp, clubObject, callback, AppControllerStatic.V1_VERSION_LATEST);
        }
    }
    
    /**
     * 8.2同城首页信息(旧版）
     *  说明：同城首页信息，包括同城车友会（<8个），同城优惠（<5个）
     	接口：/club/listLocalClubAndPromotions.do
     */
    private static final int NUM_TOP_TONGCHENG_CLUBS = 8;//前8名同城车友会

    @ResponseBody
    @RequestMapping(value = "/1.0/club/listTongChengClubs.do", method = RequestMethod.GET)
    public void listTongChengClubs(HttpServletRequest request, HttpServletResponse response) {
        WebUtils.setEncoding4App(request, response);
        //获取相关参数
        String callback = AppControllerStatic.paramCallback(request);
        long provinceId = AppControllerStatic.paramProvinceId(request);
        long cityId = AppControllerStatic.paramCityId(request);
        int xssEncode = AppControllerStatic.paramXssEncode(request);

        JSONObject jsonObject = new JSONObject();
        JSONArray jsonArray = new JSONArray();

        //provinceId为必传参数
        if (provinceId == 0L) {
            AppControllerStatic.printErrorMsg(response, "非法参数provinceId！", jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }

        //获取同城车友会前3名的信息
        Pager<Club> pager = clubService.pageClubByCityId(cityId, provinceId, 1, NUM_TOP_TONGCHENG_CLUBS);
        if(pager != null && !pager.getResultList().isEmpty()) {
        	for(Club club : pager.getResultList()) {
        		JSONObject json = new JSONObject();

                json.put("clubId", club.getClubId());
                json.put("name", xssEncode > 0 ? EncodeUtils.encodeForHTMLFilterNull(club.getName()) : club.getName());
                json.put("logo", xssEncode > 0 ? EncodeUtils.encodeForHTMLFilterNull(club.getLogo()) : club.getLogo());
                json.put("url", systemConfig.getRoot() + "/" + club.getClubUrl() + "/");
                json.put("clubLevel", club.getLevelId());
                
                jsonArray.add(json);
        	}
        	
        	jsonObject.put("tongChengClubCount", pager.getTotal());
        } else {
        	jsonObject.put("tongChengClubCount", 0);
        }
        
        
        jsonObject.put("tongChengClubData", jsonArray);
        AppControllerStatic.printSuccessMsg(response, jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
    }
    
    /**
     * 8.2同城首页信息(旧版）
     *  说明：同城首页信息，包括同城车友会（<3个），同城优惠（<5个）
     	接口：/club/listLocalClubAndPromotions.do
     */
    private static final int NUM_TOP_TONGCHENG_YOUHUI = 5;//前5名同城优惠

    @ResponseBody
    @RequestMapping(value = "/1.0/club/listTongChengYouhui.do", method = RequestMethod.GET)
    public void listTongChengYouhui(HttpServletRequest request, HttpServletResponse response) {
        WebUtils.setEncoding4App(request, response);
        //获取相关参数
        String callback = AppControllerStatic.paramCallback(request);
        long provinceId = AppControllerStatic.paramProvinceId(request);
        long cityId = AppControllerStatic.paramCityId(request);
        int xssEncode = AppControllerStatic.paramXssEncode(request);

        JSONObject jsonObject = new JSONObject();
        JSONArray jsonArray = new JSONArray();

        //provinceId为必传参数
        if (provinceId == 0L) {
            AppControllerStatic.printErrorMsg(response, "非法参数provinceId！", jsonObject, callback, AppControllerStatic.V1_VERSION);
            return;
        }

        //获取同城优惠前5条的记录
        List<PromotionPublish> promotionPublishs = promotionService.listPromotionPublishByCondition(provinceId, cityId, NUM_TOP_TONGCHENG_YOUHUI);
        for (PromotionPublish promotionPublish : promotionPublishs) {
        	JSONObject json = promotionService.setPromotionPublishToJson(promotionPublish, xssEncode);
            jsonArray.add(json);
        }

        jsonObject.put("tongChengYouhuiData", jsonArray);
        jsonObject.put("tongChengYouhuiCount", promotionPublishs == null ? 0 : promotionPublishs.size());
        AppControllerStatic.printSuccessMsg(response, jsonObject, callback, AppControllerStatic.V1_VERSION);
    }
    
    /**
     * 获取同城优惠，分页，返回全部
     * @param request
     * @param response
     */
    @ResponseBody
    @RequestMapping(value = "/2.0/club/listTongChengYouhui.do", method = RequestMethod.GET)
    public void listTongChengYouhui2(HttpServletRequest request, HttpServletResponse response) {
        WebUtils.setEncoding4App(request, response);
        //获取相关参数
        String callback = AppControllerStatic.paramCallback(request);
        long provinceId = AppControllerStatic.paramProvinceId(request);
        long cityId = AppControllerStatic.paramCityId(request);
        int xssEncode = AppControllerStatic.paramXssEncode(request);
        int pageSize = AppControllerStatic.paramPageSize(request);
        int pageNo = AppControllerStatic.paramPageNo(request);

        JSONObject jsonObject = new JSONObject();
        JSONArray jsonArray = new JSONArray();

        //provinceId为必传参数
        if (provinceId == 0L) {
            AppControllerStatic.printErrorMsg(response, "省份Id不存在！", jsonObject, callback, AppControllerStatic.V2_VERSION_LATEST);
            return;
        }

        //获取同城优惠
        Pager<PromotionPublish> pager = promotionService.pagePromotionPublish(provinceId, cityId, pageNo, pageSize);
        if (pager != null && !pager.getResultList().isEmpty()) {
            for (PromotionPublish promotionPublish : pager.getResultList()) {
            	JSONObject json = promotionService.setPromotionPublishToJson(promotionPublish, xssEncode);
                jsonArray.add(json);
            }
        }

        jsonObject.put("tongChengYouhuiData", jsonArray);
        AppControllerStatic.printSuccessMsgPager(response, jsonObject, callback, pager, AppControllerStatic.V2_VERSION_LATEST);
    }

    /**
     * 2.4车友会搜索接口（旧版） 说明:搜索,精确查找,根据id查找，根据主题查找
     * 接口URL：/club/getClubByCityOrRegionId.do 请求参数： provinceId:省id
     * cityId:城市ID（无则无须传cityid） brand:品牌id seriesId:车系ID clubName:车友会名称
     * clubId:车友会ID userId:用户ID(可选) tagId：主题id
     *
     * 新接口与PC端独立区分，不进行缓存 对返回的字段进行归类
     *
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/getClubBasic.do", method = RequestMethod.GET)
    public void getClubBasic(HttpServletRequest request, HttpServletResponse response) throws IOException {
        WebUtils.setEncoding4App(request, response);
        //获取参数值
        String callback = AppControllerStatic.paramCallback(request);
        long cityId = AppControllerStatic.paramCityId(request);
        long provinceId = AppControllerStatic.paramProvinceId(request);
        long clubId = AppControllerStatic.paramClubId(request);
        int xssEncode = AppControllerStatic.paramXssEncode(request);
        int pageNo = AppControllerStatic.paramPageNo(request);
        int pageSize = AppControllerStatic.paramPageSize(request);
        long seriesId = AppControllerStatic.paramSeriesId(request);
        String[] seriesIds = WebUtils.paramTrim(request, "seriesIds", "").split(",");
        String clubName = WebUtils.paramTrim(request, "clubName", "");
        long brandId = AppControllerStatic.paramBrandId(request);
        int tabId = WebUtils.paramInt(request, "tagId", 0);//主题ID

        //转换车系ID，并保存到列表中
        List<Object> sids = new ArrayList<Object>(seriesIds.length);
        if (seriesId > 0) {
            sids.add(seriesId);
        } else {
            for (String s : seriesIds) {
                try {
                    int i = Integer.parseInt(s);
                    if (i > 0) {
                        sids.add(i);
                    }
                } catch (java.lang.NumberFormatException e) {
                    continue;
                }
            }
        }
        Pager<Club> pager = clubService.pageClubByPlaceId(cityId, 0, provinceId, brandId, sids.toArray(), clubId, clubName, pageNo, pageSize, tabId);
        JSONObject json = new JSONObject();
        if (pager != null && !pager.getResultList().isEmpty()) {
            JSONArray jsonArray = new JSONArray();
            for (Club club : pager.getResultList()) {
                //车友会基本属性
                JSONObject jsonObject = xssEncode > 0 ? club.toJsonEncodeHTML() : club.toJson();

                jsonArray.add(jsonObject);
            }
            json.put("data", jsonArray);
        } else {
            json.put("data", new JSONArray());
        }

        AppControllerStatic.printSuccessMsgPager(response, json, callback, pager, AppControllerStatic.V1_VERSION_LATEST);
    }


    /**
     * 2.18创建车友会接口（旧版） 原接口URL:/club/createClub.do 根据type来判断是创建哪一种车友会：1-》地区 2-》品牌
     * 3-》主题
     *
     * 创建品牌车友会
     *
     * @param request
     * @param response
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/createClubByBrand.do", method = RequestMethod.POST)
    public void createClubByBrand(HttpServletRequest request, HttpServletResponse response) {
        this.createClub(request, response, Club.TYPE_SERIAL);
    }

    /**
     * 2.18创建车友会接口（旧版） 原接口URL:/club/createClub.do 根据type来判断是创建哪一种车友会：1-》地区 2-》品牌
     * 3-》主题
     *
     * 创建地区车友会
     *
     * @param request
     * @param response
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/createClubByArea.do", method = RequestMethod.POST)
    public void createClubByArea(HttpServletRequest request, HttpServletResponse response) {
        this.createClub(request, response, Club.TYPE_AREA);
    }

    /**
     * 2.18创建车友会接口（旧版） 原接口URL:/club/createClub.do 根据type来判断是创建哪一种车友会：1-》地区 2-》品牌
     * 3-》主题
     *
     * 创建主题车友会
     *
     * @param request
     * @param response
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/createClubByTheme.do", method = RequestMethod.POST)
    public void createClubByTheme(HttpServletRequest request, HttpServletResponse response) {
        this.createClub(request, response, Club.TYPE_THEME);
    }

    /**
     * 建车友会入口
     *
     * @param request
     * @param response
     */
    private void createClub(HttpServletRequest request, HttpServletResponse response, int type) {
        WebUtils.setEncoding4App(request, response);
        //获取相关参数
        String callback = AppControllerStatic.paramCallback(request);
        //获取用户信息
        User user = userAuth.getUser(request, response);
        JSONObject json = new JSONObject();
        //判断用户是否登录
        if (user == null || user.getUid() <= 0) {
            AppControllerStatic.printErrorMsg(response, "用户未登录", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        //根据表单，转换车友会对象和车友会地址对象
        long userId = user.getUid();
        Club club = this.reqConvert2Club(request, userId, type);
        ClubAddress clubAddress = this.reqConvert2Address(request, userId);
        //验证表单
        String returnMessage = this.checkClubForm(club, clubAddress, request, user);
        //验证表单不通过
        if (!"true".equals(returnMessage)) {
            AppControllerStatic.printErrorMsg(response, returnMessage, json, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        //创建车友会
        long clubId = clubService.create(club, clubAddress);
        //创建车友会失败
        if (clubId <= 0) {
            AppControllerStatic.printErrorMsg(response, "创建车友会失败", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        //验证通过，绑定手机
        intfService.bindPhone(clubAddress.getPhone(), WebUtils.paramTrim(request, "code", ""),
                WebUtils.cookie(request, systemConfig.getUserSessionName()));
        //同步用户信息
        if (user.isComplete() == false) {
            user.setTruename(clubAddress.getName());
            user.setProvinceId(WebUtils.paramLong(request, "clubAddressProvinceId", 0));
            user.setProvince(clubAddress.getProvinceName());
            user.setPhone(clubAddress.getPhone());
            user.setPhoneValidated(1);
            user.setCityId(WebUtils.paramLong(request, "clubAddressCityId", 0));
            user.setCity(clubAddress.getCityName());
        }
        user.setGender(WebUtils.paramInt(request, "gender", -1));
        user.setBirthday(WebUtils.parseDate(request, "birthday"));
        userService.updateUser(user);
        //保存资料到个人中心
        int gender = user.getGender();
        String realName = clubAddress.getName();
        String phone = clubAddress.getPhone();
        long provinceId = clubAddress.getProvinceId();
        long cityId = clubAddress.getCityId();
        updateUserCenter(request, gender, realName, phone, provinceId, cityId);
        //创建成功
        AppControllerStatic.printSuccessMsg(response, json, callback, AppControllerStatic.V1_VERSION_LATEST);
    }

    /**
     * 表单转车友会对象
     *
     * @param request
     * @param userId
     * @param type 车友会类型 1:地区车友；2：车系车友；3：主题车友
     * @return
     */
    private Club reqConvert2Club(HttpServletRequest request, long userId, int type) {
        Club club = new Club();
        Date currentDate = DateUtils.getNow();
        club.setAdminId(userId);
        club.setAuditAt(null);
        club.setAuditBy(0);
        long brandId = WebUtils.paramLong(request, "brandId", 0);
        club.setBrandId(brandId);
        String brandName = WebUtils.getAreaPlaceByReq(request, "brandName", "");
        club.setBrandName(brandName);
        long cityId = WebUtils.paramLong(request, "cityId", 0);
        club.setCityId(cityId);
        String cityName = WebUtils.getAreaPlaceByReq(request, "cityName", "");
        club.setCityName(cityName);
        club.setCreateAt(currentDate);
        club.setCreateBy(userId);
        club.setIntroduce(WebUtils.param(request, "introduce", ""));
        club.setLevelId(0);
        club.setLogo("");
        club.setMemberNum(0);
        club.setName(WebUtils.paramTrim(request, "clubName", ""));
        long provinceId = WebUtils.paramLong(request, "provinceId", 0);
        long regionId = RegionUtil.getRegionId(provinceId);
        club.setProvinceId(provinceId);
        String provinceName = WebUtils.paramTrim(request, "provinceName", "");
        club.setProvinceName(provinceName);
        club.setRegionId(regionId);
        club.setRegionName(RegionUtil.getRegionName(regionId));
        club.setReplyNum(0);
        long seriesId = WebUtils.paramLong(request, "seriesId", 0);
        club.setSeriesId(seriesId);
        String seriesName = WebUtils.paramTrim(request, "seriesName", "");
        club.setSeriesName(seriesName);
        club.setStatus(Club.STATUS_UNAUDITED);
        club.setTopicNum(0);
        club.setUpdateAt(currentDate);
        club.setUpdateBy(userId);
        club.setQqGroup(WebUtils.paramTrim(request, "qqGroup", ""));
        club.setVipNum(0);
        club.setClubUrl(WebUtils.paramTrim(request, "clubUrl", "").replaceAll(" ", "").toLowerCase());
        club.setType(type);//车友会类型 1:地区车友；2：车系车友；3：主题车友
        club.setThemeId(WebUtils.paramLong(request, "themeId", 0L));//主题类型
        club.setAppBanner(WebUtils.param(request, "appBanner", ""));//车友会背景URL

        return club;
    }

    /**
     * 表单转车友会地址对象
     *
     * @param req
     * @return
     */
    private ClubAddress reqConvert2Address(HttpServletRequest request, long userId) {
        ClubAddress clubAddress = new ClubAddress();
        clubAddress.setAddress(WebUtils.paramTrim(request, "address", ""));
        clubAddress.setCityId(WebUtils.paramInt(request, "clubAddressCityId", 0));
        clubAddress.setCityName(WebUtils.getAreaPlaceByReq(request, "clubAddressCityName", ""));
        clubAddress.setName(WebUtils.paramTrim(request, "realName", ""));
        clubAddress.setPhone(WebUtils.paramTrim(request, "phone", ""));
        clubAddress.setPostcode(WebUtils.paramTrim(request, "postCode", ""));
        clubAddress.setProvinceId(WebUtils.paramInt(request, "clubAddressProvinceId", 0));
        clubAddress.setProvinceName(WebUtils.paramTrim(request, "clubAddressProvinceName", ""));
        clubAddress.setUpdateAt(DateUtils.getNow());
        clubAddress.setUpdateBy(userId);
        return clubAddress;
    }
    private final static int INPUT_MAX_LENGTH = 30;//最大可输入长度

    /**
     * 验证申请车友会信息
     *
     * @param club
     * @param req
     * @param req
     * @param user
     * @return
     */
    private String checkClubForm(Club club, ClubAddress clubAddress, HttpServletRequest request, User user) {
        //验证车友会名字
        String name = club.getName();
        String retNameMsg = clubService.checkClubName(name);
        if (!"true".equals(retNameMsg)) {
            return retNameMsg;
        }
        //验证车友会域名
        String clubUrl = club.getClubUrl();
        String retMsg = clubService.checkClubUrl(clubUrl);
        if (!"true".equals(retMsg)) {
            return retMsg;
        }
        //获取车友会相关属性进行验证
        long provinceId = club.getProvinceId();
        String provinceName = club.getProvinceName();
        long cityId = club.getCityId();
        String cityName = club.getCityName();
        long brandId = club.getBrandId();
        String brandName = club.getBrandName();
        long seriesId = club.getSeriesId();
        String seriesName = club.getSeriesName();
        int type = club.getType();
        long themeId = club.getThemeId();

        if (type == Club.TYPE_AREA) {//如果type=1,创建地区车友会；
        	if(provinceId == 0) {
        		return "非法省份ID";
        	} else if (provinceId != 0 && StringUtils.isBlank(provinceName)) {
                return "缺少省份名称";
            } else if (provinceName.length() > INPUT_MAX_LENGTH) {
                return "非法省份名称";
            }
            if (cityId != 0 && StringUtils.isBlank(cityName)) {
                return "缺少城市名称";
            } else if (cityName.length() > INPUT_MAX_LENGTH) {
                return "非法城市名称";
            }
            //不能传主题ID
            if(themeId > 0) {
            	return "非主题车友会，非法参数themeId";
            }
        } else if (type == Club.TYPE_SERIAL) {//如果type=2,创建品牌/车系车友会；
        	if(brandId == 0) {
        		return "非法品牌ID";
        	} else if (brandId != 0 && StringUtils.isBlank(brandName)) {
                return "缺少品牌名称";
            } else if (brandName.length() > INPUT_MAX_LENGTH) {
                return "非法品牌名称";
            }
            if (seriesId != 0 && StringUtils.isBlank(seriesName)) {
                return "缺少车系名称";
            } else if (seriesName.length() > INPUT_MAX_LENGTH) {
                return "非法车系名称";
            }
            //不能传主题ID
            if(themeId > 0) {
            	return "非主题车友会，非法参数themeId";
            }
        } else if (type == Club.TYPE_THEME) {//如果type=3,创建主题车友会；
            Theme theme = themeService.findThemeById(themeId);
            if (theme == null) {
                return "非法参数themeId";
            }
        } else {
            return "车友会类型错误";
        }
        //不可以只选择城市，不选择省份
        if (provinceId == 0 && cityId != 0) {//非法操作
            return "缺少省份";
        }
        //不可以只选择车系，不选择品牌
        if (brandId == 0 && seriesId != 0) {//非法操作
            return "缺少车型";
        }
        //QQGroup检查
        String qqGroup = club.getQqGroup();
        String qqGroupMsg = clubService.checkClubQQGroup(qqGroup);
        if (!"true".equals(qqGroupMsg)) {
            return qqGroupMsg;
        }
        //汉字、英文、数字、下横线、英文横线
        String realName = clubAddress.getName();
        String retRealNameMsg = clubService.checkRealName(realName);
        if (!"true".equals(retRealNameMsg)) {
            return retRealNameMsg;
        }
        //验证车友会申请人手机号码
        String phone = clubAddress.getPhone();
        String retPhoneMsg = clubService.checkClubPhone(phone);
        if (!"true".equals(retPhoneMsg)) {
            return retPhoneMsg;
        }
        //验证车友会申请 人性别
        int gender = WebUtils.paramInt(request, "gender", -1);
        if (gender == -1) {
            return "请选择性别";
        }
        //验证车友会验证码
        String checkcode = WebUtils.paramTrim(request, "code", "");
        if (StringUtils.isBlank(checkcode)) {
            return "请输入验证码";
        }
        if (systemConfig.isNeedCheckCode()) {
            String checkCodeMsg = checkPhoneCode(phone, checkcode);
            if (StringUtils.isNotEmpty(checkCodeMsg)) {
                return checkCodeMsg;
            }
        }
        //条款
        int agree = WebUtils.paramInt(request, "agree", -1);
        if (agree == -1) {
            return "请阅读并同意《中国车友会管理条例》";
        }
        //验证是否已经加入过车友会，或者申请加入车友会中
        String tip = this.checkJoinedClub(user);
        if (StringUtils.isNotEmpty(tip)) {
            return tip;
        }
        //通过验证
        return "true";
    }

    /**
     * 返回验证结果，如果为空串就表示验证通过，否则返回验证信息
     *
     * @param phone
     * @param code
     * @return
     */
    private String checkPhoneCode(String phone, String code) {
        String relUrl = systemConfig.getRoot() + "/ClubController.found.checkPhoneCode";
        String url = systemConfig.getCheckCodeUrl();
        String result = simpleHttpTemplate.post(url, relUrl, null,
                new ResponseExtractor<String>() {
                    @Override
                    public String extractData(HttpResponse response) {
                        StatusLine statusLine = response.getStatusLine();
                        if (statusLine.getStatusCode() == 200) {
                            try {
                                return EntityUtils.toString(response.getEntity());
                            } catch (IOException ex) {
                                log.error("checPhoneCode fail 1!", ex);
                            } catch (ParseException ex) {
                                log.error("checPhoneCode fail 2!", ex);
                            }
                        } else {
                            log.error("checPhoneCode fail statusCode is " + statusLine.getStatusCode());
                            try {
                                log.error(EntityUtils.toString(response.getEntity()));
                            } catch (IOException ex) {
                                log.error("checkAndSetUser error", ex);
                            } catch (ParseException ex) {
                                log.error("checkAndSetUser error", ex);
                            }
                        }
                        return null;
                    }
                },
                EntityBuilder.entity().param("type", "autoClub").param("act", "check").param("mobile", phone).param("verificationCode", code).build(), 3000);
        JSONObject rs = JSONObject.parseObject(result);
        if (rs == null) {
            return "手机验证出错，请稍后重试";
        }
        int c = rs.getIntValue("code");
        if (c == 0) {
            return "";
        }
        return rs.getString("message");
    }

    /**
     * 判断用户是否已经加入过车会，如果已经加入过，或者申请中的用户不可以创建车友会
     *
     * @param user
     * @return
     */
    private String checkJoinedClub(User user) {
        int limit = Integer.parseInt(systemConfig.getJoinClubLimit());
        String tip = "";
        int count = userService.updateJoinedClubCount(user);
        if (count >= limit) {
            tip = "您已加入其他车友会，无法创建新的车友会！";
            return tip;
        }
        count += memberService.findMemberApplication(user.getUid(), 0l, true).size();
        if (count >= limit) {
            tip = "您已申请加入其他车友会，正在审核中，无法创建新的车友会！";
            return tip;
        }
        count += clubService.findByFounder(user.getUid(), false).size();
        if (count >= limit) {
            tip = "您申请创建的车友会正在审核中，请耐心等待审核结果！";
            return tip;
        }
        return tip;
    }

    /**
     * 2.19修改车友会接口(旧版） 接口URL:/club/editClub.do 说明:修改车友会资料 请求参数： clubId:车友会ID
     * userId：用户Id，从登录信息取 editType：1》会标修改，2》宣言修改，3》公告修改 4》顶部背景
     * content：修改内容（url/宣言/公告/顶部背景，传url） 修改车友会信息接口,包括：会标修改，宣言(简介)修改，车友会公告 顶部背景
     *
     * 此接口只修改车友会信息,修改公告为单独接口
     *
     * @throws
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/editClub.do", method = RequestMethod.POST)
    public void editClub(HttpServletRequest request, HttpServletResponse response) {
        WebUtils.setEncoding4App(request, response);
        //获取相关参数
        long clubId = AppControllerStatic.paramClubId(request);
        String logo = WebUtils.param(request, "logo", "");
        String introduce = WebUtils.param(request, "introduce", "");
        String appBanner = WebUtils.param(request, "appBanner", "");
        String callback = AppControllerStatic.paramCallback(request);

        JSONObject json = new JSONObject();
        //判断用户是否登录
        User user = userAuth.getUser(request, response);
        if (user == null || user.getUid() <= 0) {
            AppControllerStatic.printErrorMsg(response, "您还没有登录", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        //判断是否为管理员
        if (!memberService.isClubNormalAdmin(user.getUid(), clubId)) {
            AppControllerStatic.printErrorMsg(response, "您不是该车友会管理员，只有管理员才能进行该操作哦！", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        //判断车友会是否合法
        Club club = clubService.getValidClub(clubId);
        if (club == null) {
            AppControllerStatic.printErrorMsg(response, "该车友会ID不存在", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        //检验Logo字段
        if (StringUtils.isBlank(logo)) {
            AppControllerStatic.printErrorMsg(response, "上传logo不允许为空！", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        //检验Logo长度
        if (logo.length() > 255) {
            AppControllerStatic.printErrorMsg(response, "上传logo长度不能超过255！", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        //检验introduce字段
        if (introduce.length() > 45) {
            AppControllerStatic.printErrorMsg(response, "简介长度不能超过45！", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        //检验appBanner字段

        /*if (StringUtils.isBlank(appBanner)) {
            AppControllerStatic.printErrorMsg(response, "背景URL不允许为空！", json, callback, AppControllerStatic.V1_VERSION_LATEST);

            return;
        }*/
        if(appBanner.length() > 255) {
            AppControllerStatic.printErrorMsg(response, "背景URL长度不能超过255！", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        //APP3.1时，传参数尺寸为640x230, APP4.0传参数尺寸为640x800, 都保存640x230到数据库
        String appBannerNew;
        if(StringUtils.isBlank(appBanner)) {
        	appBannerNew = "";
        } else {
        	appBannerNew = appBanner.replace("640x800", "640x230");
        }
        club.setAppBanner(appBannerNew);
        
        //保存车友会修改
        club.setLogo(logo);
        club.setIntroduce(introduce);
        int resultCode = geliDao.update(club, "logo,introduce,appBanner");
        if (resultCode == 0) {
            AppControllerStatic.printErrorMsg(response, "更新车友会资料失败！", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }

        AppControllerStatic.printSuccessMsg(response, json, callback, AppControllerStatic.V1_VERSION_LATEST);
    }
    
    /**
     * 修改车友会公告接口
     * @throws
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/editClubNotice.do", method = RequestMethod.POST)
    public void editClubNotice(HttpServletRequest request, HttpServletResponse response) {
        WebUtils.setEncoding4App(request, response);
        //获取相关参数
        long clubId = AppControllerStatic.paramClubId(request);
        String content = WebUtils.param(request, "notice", "");
        String callback = AppControllerStatic.paramCallback(request);

        JSONObject json = new JSONObject();
        //判断用户是否登录
        User user = userAuth.getUser(request, response);
        if (user == null || user.getUid() <= 0) {
            AppControllerStatic.printErrorMsg(response, "您还没有登录", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        //判断是否为管理员
        if (!memberService.isClubNormalAdmin(user.getUid(), clubId)) {
            AppControllerStatic.printErrorMsg(response, "您不是该车友会管理员，只有管理员才能进行该操作哦！", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        //判断车友会是否合法
        Club club = clubService.getValidClub(clubId);
        if (club == null) {
            AppControllerStatic.printErrorMsg(response, "该车友会ID不存在", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        //检验notice字段

        if (StringUtil.length(content) > 100) {
            AppControllerStatic.printErrorMsg(response, "通知长度不能超过100！", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        ClubNotice notice = clubService.getNotice(club.getClubId());
        if (!notice.getContent().equals(content)) {
        	ClubNotice newClubNotice = clubService.saveNotice(club.getClubId(), content, user.getUid());
            if(!StringUtils.isBlank( content )){
                //更新完发动态
                AbstractDyna d = new AbstractDyna();
                d.setClubId(club.getClubId());
                d.setContent(content);
                d.setTargetId(club.getClubId());
                d.setCreateBy(user.getUid());
                d.setCreateName(user.getNickname());
                d.setCreateDate(newClubNotice.getUpdateAt());
                long dynaInfoId = dynaService.createNoticeDyna(d, null);
                //发审核
                censorNoticeService.notifyCensorSystemCreate(request, notice, dynaInfoId);
                List<ClubMember> members = memberService.listMemberByClubId(club.getClubId());
                for(ClubMember u : members) {
                    if(u.getUid() != user.getUid()) {
                        //会长修改公告，通知用户
                        messageService.send(u.getUser(), MessageService.NEW_NOTICE,
                                   messageService.assembleUserUrl(user.getUid(), user.getNickname()), messageService.assembleNoticeUrl(club.getClubUrl(), dynaInfoId, content)); 
                    }
                }
            }
        }
        AppControllerStatic.printSuccessMsg(response, json, callback, AppControllerStatic.V1_VERSION_LATEST);

    }

    private static final int SORT_RANGE_NUM = 2;//车友会排名范围值
    /**
     * 2.29车友会排行榜接口（旧版） 接口URL:/club/listTopClubWeekly.do 说明:top10认证人数,全国油值排行榜
     * 请求参数： type:0:上周新增认证人数排行,1:上周新增油值排行 2全国排名 3品牌排名 4地区排名 userId:用户id(可选)
     * showType:是否需要返回后面数组，用于首页排行榜是否有变化显示，0则返回下面所有信息，1则只返回排名变化（前六个字段），默认0
     *
     * 新接口按照type拆分独立的接口--全国排名
     *
     * @param req
     * @param resp
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/listTopClubWeeklyByNationwide.do", method = RequestMethod.GET)
    public void listTopClubWeeklyByNationwide(HttpServletRequest request, HttpServletResponse response) {
        WebUtils.setEncoding4App(request, response);
        //缓存半小时
        WebUtils.setCacheHeader(response, 1800);
        //获取相关参数
        String callback = AppControllerStatic.paramCallback(request);
        long userId = AppControllerStatic.paramUserId(request);
        int xssEncode = AppControllerStatic.paramXssEncode(request);

        JSONObject json = new JSONObject();
        User user = userService.findUser(userId);
        ClubMember clubMember = null;

        //根据用户获取车友会信息
        if (user != null && user.getUid() > 0) {
            clubMember = memberService.findClubMemberByUserId(user.getUid());
        }

        //定义相关变量
        int rank = 0;
        long clubId = 0;

        // 如果此用户已经加入车友会,返回车友会全国，车系，地区排名
        if (clubMember != null) {
            Club club = clubService.getClub(clubMember.getClubId());
            if (club != null) {
                clubId=club.getClubId();
                //新旧全车排名
                rank = club.getRank();
                int dayRank = club.getDayRank();
                //新旧品牌排名
                int brandRank = club.getBrandRank();
                int dayBrandRank = club.getDayBrandRank();
                //新旧地区排名
                int provinceRank = club.getProvinceRank();
                int dayProvinceRank = club.getDayProvinceRank();
                //如果昨天的全国排名为0，不参与排名升降比较
                json.put("rank", rank);
                json.put("rankAsc", dayRank == 0 ? 0 : dayRank - rank);
                //如果昨天的品牌排名为0，不参与排名升降比较
                json.put("brandRank", brandRank);
                json.put("brandRankAsc", dayBrandRank == 0 ? 0 : dayBrandRank - brandRank);
                //如果昨天的地区排名为0，不参与排名升降比较
                json.put("provinceRank", provinceRank);
                json.put("provinceRankAsc", dayProvinceRank == 0 ? 0 : dayProvinceRank - provinceRank);
            }
        }
        //前20名是定时任务一天算一次的，所以可以放入到MC里面。跟原来不放MC相比，差别在于，车友会的信息也会缓存一天，不过问题不大。
        //获取车友会品牌排名前20
        McUtils key20 = new McUtils(mcc,McUtils.listTopClubWeeklyByNationwideKey,clubId,DateUtils.getTodayYmd());
        JSONArray arr = key20.get();
        if(arr==null){
            arr = new JSONArray();
            //获取车友会全国排名前20
            List<Club> list = clubService.listClubBySortForList(
                    ClubService.SORT_COUNTRY_TYPE, AppControllerStatic.APP_API_DEF_PAGE_NO,
                    AppControllerStatic.APP_API_DEF_PAGE_SIZE, 0L, 0L, 0, 0);
            for (Club club : list) {
                JSONObject obj = xssEncode > 0 ? club.toJsonEncodeHTML() : club.toJson();
                arr.add(obj);
            }
            key20.set(arr);
        }

         //获取本车友会排名的前后2名
        McUtils key5 = new McUtils(mcc,McUtils.list5ClubWeeklyByNationwideKey,clubId,DateUtils.getTodayYmd());
        JSONArray arrIndex = key5.get();
        if(arrIndex==null){
            arrIndex = new JSONArray();
            if (rank > 0L) {
               //获取本车友会前后2名的范围，开始排名与结束排名
               int beginRank = rank - SORT_RANGE_NUM <= 0 ? 1 : rank - SORT_RANGE_NUM;
               int endRank = rank + SORT_RANGE_NUM;
               //获取排名范围列表
               List<Club> list5Clubs = clubService.listClubBySortForList(ClubService.SORT_COUNTRY_TYPE,
                       AppControllerStatic.APP_API_DEF_PAGE_NO, AppControllerStatic.APP_API_DEF_PAGE_SIZE, 0L, 0L, beginRank, endRank);
               for (Club club : list5Clubs) {
                   JSONObject obj = xssEncode > 0 ? club.toJsonEncodeHTML() : club.toJson();
                   arrIndex.add(obj);
               }
               key5.set(arrIndex);
           }
        }

        //返回相关操作
        json.put("data", arr);
        json.put("clubIndexData", arrIndex);
        AppControllerStatic.printSuccessMsg(response, json, callback, AppControllerStatic.V1_VERSION_LATEST);
    }

    /**
     * 2.29车友会排行榜接口（旧版） 接口URL:/club/listTopClubWeekly.do 说明:top10认证人数,全国油值排行榜
     * 请求参数： type:0:上周新增认证人数排行,1:上周新增油值排行 2全国排名 3品牌排名 4地区排名 userId:用户id(可选)
     * showType:是否需要返回后面数组，用于首页排行榜是否有变化显示，0则返回下面所有信息，1则只返回排名变化（前六个字段），默认0
     *
     * 新接口按照type拆分独立的接口--品牌排名
     *
     * @param req
     * @param resp
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/listTopClubWeeklyByBrand.do", method = RequestMethod.GET)
    public void listTopClubWeeklyByBrand(HttpServletRequest request, HttpServletResponse response) {
        WebUtils.setEncoding4App(request, response);
        //缓存半小时
        WebUtils.setCacheHeader(response, 1800);
        //获取相关参数
        String callback = AppControllerStatic.paramCallback(request);
        long userId = AppControllerStatic.paramUserId(request);
        int xssEncode = AppControllerStatic.paramXssEncode(request);

        JSONObject json = new JSONObject();
        User user = userService.findUser(userId);
        ClubMember clubMember = null;
        //根据用户获取车友会信息
        if (user != null && user.getUid() > 0) {
            clubMember = memberService.findClubMemberByUserId(user.getUid());
        }

        //定义相关变量
        int brandRank = 0;
        long brandIdByClub = 0L;
        long clubId=0;

        // 如果此用户已经加入车友会,返回车友会全国，车系，地区排名
        if (clubMember != null) {
            Club club = clubService.getClub(clubMember.getClubId());
            if (club != null) {
                clubId = club.getClubId();
                //新旧全车排名
                int rank = club.getRank();
                int dayRank = club.getDayRank();
                //新旧品牌排名
                brandRank = club.getBrandRank();
                int dayBrandRank = club.getDayBrandRank();
                //新旧地区排名
                int provinceRank = club.getProvinceRank();
                int dayProvinceRank = club.getDayProvinceRank();

                brandIdByClub = club.getBrandId();

                //如果昨天的全国排名为0，不参与排名升降比较
                json.put("rank", rank);
                json.put("rankAsc", dayRank == 0 ? 0 : dayRank - rank);
                //如果昨天的品牌排名为0，不参与排名升降比较
                json.put("brandRank", brandRank);
                json.put("brandRankAsc", dayBrandRank == 0 ? 0 : dayBrandRank - brandRank);
                //如果昨天的地区排名为0，不参与排名升降比较
                json.put("provinceRank", provinceRank);
                json.put("provinceRankAsc", dayProvinceRank == 0 ? 0 : dayProvinceRank - provinceRank);
            }
        }
        //前20名是定时任务一天算一次的，所以可以放入到MC里面。跟原来不放MC相比，差别在于，车友会的信息也会缓存一天，不过问题不大。
        //获取车友会品牌排名前20
        McUtils key20 = new McUtils(mcc,McUtils.listTopClubWeeklyByBrandKey,brandIdByClub,clubId,DateUtils.getTodayYmd());
        JSONArray arr = key20.get();
        if(arr==null){
            arr = new JSONArray();
            List<Club> list = clubService.listClubBySortForList(
                    ClubService.SORT_SERIES_TYPE, AppControllerStatic.APP_API_DEF_PAGE_NO,
                    AppControllerStatic.APP_API_DEF_PAGE_SIZE, brandIdByClub, 0L, 0, 0);
            for (Club club : list) {
                JSONObject obj = xssEncode > 0 ? club.toJsonEncodeHTML() : club.toJson();
                arr.add(obj);
            }
            key20.set(arr);
        }

        //获取本车友会排名的前后2名
        McUtils key5 = new McUtils(mcc,McUtils.list5ClubWeeklyByBrandKey,brandIdByClub,clubId,DateUtils.getTodayYmd());
        JSONArray arrIndex = key5.get();
        if(arrIndex==null){
            arrIndex = new JSONArray();
            if (brandRank > 0L) {
                //获取本车友会前后2名的范围，开始排名与结束排名
                int beginRank = brandRank - SORT_RANGE_NUM <= 0 ? 1 : brandRank - SORT_RANGE_NUM;
                int endRank = brandRank + SORT_RANGE_NUM;
                //获取排名范围列表
                List<Club> list5Clubs = clubService.listClubBySortForList(
                        ClubService.SORT_SERIES_TYPE, AppControllerStatic.APP_API_DEF_PAGE_NO,
                        AppControllerStatic.APP_API_DEF_PAGE_SIZE, brandIdByClub, 0L, beginRank, endRank);
                for (Club club : list5Clubs) {
                    JSONObject obj = xssEncode > 0 ? club.toJsonEncodeHTML() : club.toJson();
                    arrIndex.add(obj);
                }
                key5.set(arrIndex);
            }
        }
        //返回相关操作
        json.put("data", arr);
        json.put("clubIndexData", arrIndex);
        AppControllerStatic.printSuccessMsg(response, json, callback, AppControllerStatic.V1_VERSION_LATEST);
    }

    /**
     * 2.29车友会排行榜接口（旧版） 接口URL:/club/listTopClubWeekly.do 说明:top10认证人数,全国油值排行榜
     * 请求参数： type:0:上周新增认证人数排行,1:上周新增油值排行 2全国排名 3品牌排名 4地区排名 userId:用户id(可选)
     * showType:是否需要返回后面数组，用于首页排行榜是否有变化显示，0则返回下面所有信息，1则只返回排名变化（前六个字段），默认0
     *
     * 新接口按照type拆分独立的接口--地区排名
     *
     * @param req
     * @param resp
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/listTopClubWeeklyByArea.do", method = RequestMethod.GET)
    public void listTopClubWeeklyByArea(HttpServletRequest request, HttpServletResponse response) {
        WebUtils.setEncoding4App(request, response);
        //缓存半小时
        WebUtils.setCacheHeader(response, 1800);
        //获取相关参数
        String callback = AppControllerStatic.paramCallback(request);
        long userId = AppControllerStatic.paramUserId(request);
        int xssEncode = AppControllerStatic.paramXssEncode(request);

        JSONObject json = new JSONObject();
        User user = userService.findUser(userId);
        ClubMember clubMember = null;

        //根据用户获取车友会信息
        if (user != null && user.getUid() > 0) {
            clubMember = memberService.findClubMemberByUserId(user.getUid());
        }

        //定义相关变量
        int provinceRank = 0;
        long provinceIdByClub = 0L;
        long clubId=0;

        // 如果此用户已经加入车友会,返回车友会全国，车系，地区排名
        if (clubMember != null) {
            Club club = clubService.getClub(clubMember.getClubId());
            if (club != null) {
                clubId = club.getClubId();
                //新旧全车排名
                int rank = club.getRank();
                int dayRank = club.getDayRank();
                //新旧品牌排名
                int brandRank = club.getBrandRank();
                int dayBrandRank = club.getDayBrandRank();
                //新旧地区排名
                provinceRank = club.getProvinceRank();
                int dayProvinceRank = club.getDayProvinceRank();

                provinceIdByClub = club.getProvinceId();

                //如果昨天的全国排名为0，不参与排名升降比较
                json.put("rank", rank);
                json.put("rankAsc", dayRank == 0 ? 0 : dayRank - rank);
                //如果昨天的品牌排名为0，不参与排名升降比较
                json.put("brandRank", brandRank);
                json.put("brandRankAsc", dayBrandRank == 0 ? 0 : dayBrandRank - brandRank);
                //如果昨天的地区排名为0，不参与排名升降比较
                json.put("provinceRank", provinceRank);
                json.put("provinceRankAsc", dayProvinceRank == 0 ? 0 : dayProvinceRank - provinceRank);
            }
        }
        //前20名是定时任务一天算一次的，所以可以放入到MC里面。跟原来不放MC相比，差别在于，车友会的信息也会缓存一天，不过问题不大。
        //获取地区车友会排名前20
        McUtils key20 = new McUtils(mcc,McUtils.listTopClubWeeklyByAreaKey,provinceIdByClub,clubId,DateUtils.getTodayYmd());
        JSONArray arr = key20.get();
        if(arr==null){
            arr = new JSONArray();
            List<Club> list = clubService.listClubBySortForList(
                    ClubService.SORT_REGION_TYPE, AppControllerStatic.APP_API_DEF_PAGE_NO,
                    AppControllerStatic.APP_API_DEF_PAGE_SIZE, 0L, provinceIdByClub, 0, 0);
            for (Club club : list) {
                JSONObject obj = xssEncode > 0 ? club.toJsonEncodeHTML() : club.toJson();
                arr.add(obj);
            }
            key20.set(arr);
        }
        //获取本车友会排名的前后2名
        McUtils key5 = new McUtils(mcc,McUtils.list5ClubWeeklyByAreaKey,provinceIdByClub,clubId,DateUtils.getTodayYmd());
        JSONArray arrIndex = key5.get();
        if(arrIndex==null){
            arrIndex = new JSONArray();
            if (provinceRank > 0L) {
                //获取本车友会前后2名的范围，开始排名与结束排名
                int beginRank = provinceRank - SORT_RANGE_NUM <= 0 ? 1 : provinceRank - SORT_RANGE_NUM;
                int endRank = provinceRank + SORT_RANGE_NUM;
                //获取排名范围列表
                List<Club> list5Clubs = clubService.listClubBySortForList(
                        ClubService.SORT_REGION_TYPE, AppControllerStatic.APP_API_DEF_PAGE_NO,
                        AppControllerStatic.APP_API_DEF_PAGE_SIZE, 0L, provinceIdByClub, beginRank, endRank);
                for (Club club : list5Clubs) {
                    JSONObject obj = xssEncode > 0 ? club.toJsonEncodeHTML() : club.toJson();
                    arrIndex.add(obj);
                }
                key5.set(arrIndex);
            }
        }

        //返回相关操作
        json.put("data", arr);
        json.put("clubIndexData", arrIndex);
        AppControllerStatic.printSuccessMsg(response, json, callback, AppControllerStatic.V1_VERSION_LATEST);
    }
    private static final int ADMIN_TYPE_APPLYING = -2;//审核中的用户权限值
    private static final int ADMIN_TYPE_APPLYING_CLUB = -3;//创建车友会在审核中的用户权限值
    private static final int IS_CHECKIN_TODAY = 1;//今天已经签到
    private static final int IS_NOT_CHECKIN_TODAY = 0; //今天还没有签到

    /**
     * 用户权限获取
     *
     * @param request
     * @param response
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/user/getUserPermission.do", method = RequestMethod.GET)
    public void getUserPermission(HttpServletRequest request, HttpServletResponse response) {
        WebUtils.setEncoding4App(request, response);
        String callback = AppControllerStatic.paramCallback(request);

        JSONObject jsonObject = new JSONObject();
        JSONArray jsonArray = new JSONArray();

        //获取用户登录信息
        User user = userAuth.getUser(request, response);

        if (user == null || user.getUid() == 0) {
            AppControllerStatic.printErrorMsg(response, "用户末登录", jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }

        //获取用户是已加入车友会列表
        List<Club> clubs = clubService.listByUserId(user.getUid());
        for (Club club : clubs) {
            JSONObject json = new JSONObject();
            json.put("clubId", club.getClubId());
            ClubMember clubMember = memberService.findMember(user.getUid(), club.getClubId());
            if (clubMember != null) {
                json.put("adminType", clubMember.getAdminType());
            } else {
                json.put("adminType", "");
            }
            boolean isCheckIn = checkInService.isCheckInToday(user.getUid(), club.getClubId());
            json.put("checkIn", isCheckIn == true ? IS_CHECKIN_TODAY : IS_NOT_CHECKIN_TODAY);//1：今天已签到；0：今天未签到
            json.put("clubName", club.getName());
            json.put("memberId", clubMember.getId());
            json.put("provinceName", club.getProvinceName());
            json.put("brandName", club.getBrandName());
            List<ClubForum> clubForums = clubService.getForumList(club.getClubId());
            json.put("forumId", clubForums.isEmpty() ? 0 : clubForums.get(0).getForumId());
            jsonArray.add(json);
        }

        //获取用户在审核中的车友会列表
        List<MemberApplication> memberApplications = memberService.listMemberApplication(user.getUid(), MemberApplication.STATUS_UNAUDITED);
        for (MemberApplication memberApplication : memberApplications) {
            JSONObject json = new JSONObject();
            json.put("clubId", memberApplication.getClubId());
            json.put("adminType", ADMIN_TYPE_APPLYING);
            json.put("checkIn", IS_NOT_CHECKIN_TODAY);//1：今天已签到；0：今天未签到
            
            Club club = clubService.getClub(memberApplication.getClubId());
            json.put("clubName", club.getName());
            
            json.put("memberId", "");
            json.put("provinceName", club.getProvinceName());
            json.put("brandName", club.getBrandName());
            List<ClubForum> clubForums = clubService.getForumList(club.getClubId());
            json.put("forumId", clubForums.isEmpty() ? 0 : clubForums.get(0).getForumId());
            
            jsonArray.add(json);
        }
        
        //获取用户创建车友会，还在审核中的
        List<Integer> clubStatusList = new ArrayList<Integer>();
        clubStatusList.add(Club.STATUS_UNAUDITED);//未审的车友会
        clubStatusList.add(Club.STATUS_REJECTED);//被拒绝的车友会
        List<Club> applyingClubs = clubService.listClubsByStatus(user.getUid(), clubStatusList);
        for (Club club : applyingClubs) {
            JSONObject json = new JSONObject();
            json.put("clubId", club.getClubId());
            json.put("adminType", ADMIN_TYPE_APPLYING_CLUB);
            json.put("checkIn", IS_NOT_CHECKIN_TODAY);//1：今天已签到；0：今天未签到
            
            json.put("clubName", club.getName());
            
            json.put("memberId", "");
            json.put("provinceName", club.getProvinceName());
            json.put("brandName", club.getBrandName());
            List<ClubForum> clubForums = clubService.getForumList(club.getClubId());
            json.put("forumId", clubForums.isEmpty() ? 0 : clubForums.get(0).getForumId());
            
            jsonArray.add(json);
        }

        jsonObject.put("permissions", jsonArray);
        AppControllerStatic.printSuccessMsg(response, jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
    }
    
    private static final int NUM_TOP_RECOMMEND_CLUB = 15;//首页推荐车友会数

    /**
     * 首页车友会列表接口(游客的推荐） 返回15条数据
     * 根据cityId查找车友会，如果没有记录，就按provinceId进行查找，如果也没有记录，就按全国排行查找车友会；
     * 根据cityId查找车友会，如果有记录，直接返回列表，就算车友会数量小于15，也不再按provinceId进行查找。
     *
     * @param request
     * @param response
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/getRecommendClubs.do", method = RequestMethod.GET)
    public void getRecommendClubs(HttpServletRequest request, HttpServletResponse response) {
        WebUtils.setEncoding4App(request, response);
        WebUtils.setCacheHeader(response, 3600);//缓存一小时 
        //排名是定时任务一天算一次的，所以可以放入到MC里面。跟原来不放MC相比，差别在于，车友会的信息也会缓存一天，不过问题不大。
        String callback = AppControllerStatic.paramCallback(request);
        int xssEncode = AppControllerStatic.paramXssEncode(request);
        long proviceId = AppControllerStatic.paramProvinceId(request);
        long cityId = AppControllerStatic.paramCityId(request);
        JSONObject jsonObject = new JSONObject();

        //省份ID必填
        if (proviceId == 0) {
            AppControllerStatic.printErrorMsg(response, "非法参数provinceId", jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }

        McUtils key = new McUtils(mcc,McUtils.getRecommendClubsByPidAndCidKey,proviceId,cityId,DateUtils.getTodayYmd());
        JSONArray jsonArray = key.get();
        if(jsonArray==null){
            jsonArray = new JSONArray();
            //根据cityId获取前15名车友会
            List<Club> clubs = new ArrayList<Club>();
            if(cityId > 0) {
                    clubs = clubService.listClubByCityId(cityId, 0L, NUM_TOP_RECOMMEND_CLUB);
            }
            //根据provinceId获取前15名车友会
            if (clubs.isEmpty()) {
                    clubs = clubService.listClubByCityId(0L, proviceId, NUM_TOP_RECOMMEND_CLUB);
            }
            //获取全国排名前15名车友会
            if (clubs.isEmpty()) {
                    clubs = clubService.listClubByCityId(0L, 0L, NUM_TOP_RECOMMEND_CLUB);
            }

            //组装Json数据
            for (Club club : clubs) {
                JSONObject json = new JSONObject();
                json.put("clubId", club.getClubId());
                json.put("memberNum", club.getMemberNum());
                json.put("level", club.getLevelId());
                if (xssEncode > 0) {
                    json.put("name", EncodeUtils.encodeForHTMLFilterNull(club.getName()));
                    json.put("logo", EncodeUtils.encodeForHTMLFilterNull(club.getLogo()));
                    json.put("seriesName", EncodeUtils.encodeForHTMLFilterNull(club.getSeriesName()));
                } else {
                    json.put("name", club.getName());
                    json.put("logo", club.getLogo());
                    json.put("seriesName", club.getSeriesName());
                }
                jsonArray.add(json);
            }
            key.set(jsonArray);
        }

        //返回Json
        jsonObject.put("recommendClubs", jsonArray);
        AppControllerStatic.printSuccessMsg(response, jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
    }

    /**
     * 根据用户ID获取此用户正在被审核加入的车友会列表
     *
     * @param request
     * @param response
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/getApplyClubs.do", method = RequestMethod.GET)
    public void getApplyClubs(HttpServletRequest request, HttpServletResponse response) {
        WebUtils.setEncoding4App(request, response);
        String callback = AppControllerStatic.paramCallback(request);
        int xssEncode = AppControllerStatic.paramXssEncode(request);

        JSONObject jsonObject = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        
        User user = userAuth.getUser(request, response);
        if(user == null || user.getUid() < 0) {
        	AppControllerStatic.printErrorMsg(response, "用户未登录", jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }

        long userId = user.getUid();
        
        //用户正在被审核加入车友会申请列表
        List<MemberApplication> memberApplications = memberService.
                listMemberApplication(userId, MemberApplication.STATUS_UNAUDITED);

        //组装Json数据
        for (MemberApplication memberApplication : memberApplications) {
            Club club = clubService.getClub(memberApplication.getClubId());
            JSONObject json = new JSONObject();
            json.put("clubId", club.getClubId());
            json.put("memberNum", club.getMemberNum());
            json.put("level", club.getLevelId());
            if (xssEncode > 0) {
                json.put("name", EncodeUtils.encodeForHTMLFilterNull(club.getName()));
                json.put("logo", EncodeUtils.encodeForHTMLFilterNull(club.getLogo()));
                json.put("seriesName", EncodeUtils.encodeForHTMLFilterNull(club.getSeriesName()));
            } else {
                json.put("name", club.getName());
                json.put("logo", club.getLogo());
                json.put("seriesName", club.getSeriesName());
            }

            jsonArray.add(json);
        }

        //返回Json
        jsonObject.put("applyClubs", jsonArray);
        AppControllerStatic.printSuccessMsg(response, jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
    }

    /**
     * 根据车友会ID,获取车友会详情
     *
     * @param request
     * @param response
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/getClubDetail.do", method = RequestMethod.GET)
    public void getClubDetail(HttpServletRequest request, HttpServletResponse response) {
        WebUtils.setEncoding4App(request, response);
        String callback = AppControllerStatic.paramCallback(request);
        int xssEncode = AppControllerStatic.paramXssEncode(request);
        long clubId = AppControllerStatic.paramClubId(request);
        String clubUrl = AppControllerStatic.paramClubUrl(request);
        
        JSONObject jsonObject = new JSONObject();
        
        //检查参数，不可以两个参数同时为空值
        if (clubId == 0 && StringUtils.isBlank(clubUrl)) {
            AppControllerStatic.printErrorMsg(response, "clubId,clubUrl不可以同时为空", jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        
        Club club;
        //如果clubId不为空，以clubId为准查找数据
        if (clubId > 0) {
        	club = clubService.getClub(clubId);
        } else {//否则，根据域名查找车友会
        	club = clubService.getClubByUrl(clubUrl);
        }

        //检查车友会是否在在
        if (club == null || club.getStatus() == Club.STATUS_REJECTED || club.getStatus() == Club.STATUS_UNAUDITED) {
            AppControllerStatic.printErrorMsg(response, "此车友会不存在", jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        
        //如果是根据clubUrl查找车友会，要为clubId重新赋值
        clubId = club.getClubId();
        
        //获取车友会基本信息
        jsonObject = xssEncode == 0 ? club.toJson() : club.toJsonEncodeHTML();
        jsonObject.put("logo", club.getLogo150x150());//只返回150x150的Logo

        //车友会的相册相关
        jsonObject.put("albumSum", albumService.countAlbumByClubId(clubId));
        jsonObject.put("photoSum", albumService.countPhotoByClubId(clubId));
        //车友会的活动相关
        jsonObject.put("activitySum", activityService.countActivityByClubId(clubId));
        //车友会的等级相关
        ClubLevel clubLevel = clubLevelService.getById(club.getLevelId());
        String levelName = clubLevel == null ? "" : clubLevel.getLevelName();
        jsonObject.put("levelName", xssEncode > 0 ? EncodeUtils.encodeForHTMLFilterNull(levelName) : levelName);
        jsonObject.put("isLeastLevel", clubLevelService.isLeast(club.getLevelId()));
        //车友会的总油值
        jsonObject.put("totalPetrol", petrolService.getValidPetrol(clubId).getTotalPetrol());
        //车友会的通知内容
        String announcement = clubService.getNotice(clubId).getContent();
        jsonObject.put("announcement", xssEncode > 0 ? EncodeUtils.encodeForHTMLFilterNull(announcement) : announcement);
        //车友会的版块相关
        jsonObject.put("forumId", clubService.getFirstFormum(clubId));
        //APP3.1:640x230, APP4.0:640x800
        String appBannerOld;
        String appBannerNew;
        String appBanner = club.getAppBanner();
        if(StringUtils.isBlank(appBanner)) {
        	//对于没有设置过封面图的，默认给第一张
        	AppBanner defAppBanner = appBannerService.findById(1L);
        	appBanner = defAppBanner == null ? "" : defAppBanner.getUrl();
        } 
        
        appBannerOld = appBanner;
    	appBannerNew = appBanner.replace("640x230", "640x800");
    	
        //主题URL
        jsonObject.put("clubBackgroundImg", appBannerOld);//APP3.1
        jsonObject.put("appBanner", appBannerNew);//APP4.0
        //判断是否有升级提示
        boolean isTopLevel = clubLevelService.isHighest(club.getLevelId());
        long nextNeedPetrol = 0;
        long nextNeedVip = 0;
        if (!isTopLevel) {
            ClubLevel clubNextLevel = clubLevelService.getNextLevel(club.getLevelId());
            if (clubNextLevel != null) {
                long nextLevelId = clubNextLevel.getLevelId();
                nextNeedPetrol = clubLevelService.getNextLevelNeedPetrol(nextLevelId, (int) club.getTotalPetrol());
                nextNeedVip = clubLevelService.getNextLevelNeedMember(nextLevelId, (int) club.getVipNum());
            }
        }
        if (!isTopLevel && nextNeedVip < 1 && nextNeedPetrol < 1) {
            jsonObject.put("levelupTip", 1);//提示可升级
        } else {
            jsonObject.put("levelupTip", 0);//提示不可升级
        }
        //获取等待审核加入车友会申请数量
        try {
            List<MemberApplication> listMember4Audit = memberService.listMemberApplications4Audit(clubId);
            jsonObject.put("applyCount", listMember4Audit.size());
        } catch (EmptyResultDataAccessException e) {
            log.error("无法获取待审加入车友会成员信息clubId=" + clubId);
        }
        //会长昵称
        try {
            ClubMember adminClubMember = memberService.findAdminByClubId(clubId);
            jsonObject.put("presidentName", intfService.getNickNameByUserId(adminClubMember.getUid()));
        } catch (Exception e) {
            log.error("无法获取车友会长信息clubId=" + clubId);
        }

        AppControllerStatic.printSuccessMsg(response, jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
    }

    /**
     * 创建车友会草稿接口
     *
     * @param request
     * @param response
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/createClubDraft.do", method = RequestMethod.POST)
    public void createClubDraft(HttpServletRequest request, HttpServletResponse response) {
        WebUtils.setEncoding4App(request, response);
        String callback = AppControllerStatic.paramCallback(request);
        JSONObject json = new JSONObject();
        //获取用户信息
        User user = userAuth.getUser(request, response);
        try {
            if (user == null || user.getUid() <= 0) {
                AppControllerStatic.printErrorMsg(response, "用户未登录", json, callback, AppControllerStatic.V1_VERSION_LATEST);
                return;
            }
            long userId = user.getUid();
            //check params
            String name = WebUtils.paramTrim(request, "clubName", "");
            String retNameMsg = clubService.checkDraftName(name);
            if (!"true".equals(retNameMsg)) {
            	 AppControllerStatic.printErrorMsg(response, retNameMsg, json, callback, AppControllerStatic.V1_VERSION_LATEST);
                return;
            }
            String clubUrl = WebUtils.paramTrim(request, "clubUrl", "").replaceAll(" ", "").toLowerCase();
            String retUrlMsg = clubService.checkDraftUrl(clubUrl);
            if (!"true".equals(retUrlMsg)) {
            	AppControllerStatic.printErrorMsg(response, retUrlMsg, json, callback, AppControllerStatic.V1_VERSION_LATEST);
                return;
            }
            String provinceName = WebUtils.paramTrim(request, "provinceName", "");
            if(provinceName.length() > INPUT_MAX_LENGTH){
            	AppControllerStatic.printErrorMsg(response, "非法省份名称", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            	return;
            }
            String cityName = WebUtils.paramTrim(request, "cityName", "");
            if(cityName.length() > INPUT_MAX_LENGTH){
            	AppControllerStatic.printErrorMsg(response, "非法城市名称", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            	return;
            }
            String brandName = WebUtils.getAreaPlaceByReq(request, "brandName", "");
            if(brandName.length() > INPUT_MAX_LENGTH){
            	AppControllerStatic.printErrorMsg(response, "非法品牌名称", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            	return;
            }
            String seriesName = WebUtils.paramTrim(request, "seriesName", "");
            if(seriesName.length() > INPUT_MAX_LENGTH){
            	AppControllerStatic.printErrorMsg(response, "非法车系名称", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            	return;
            }
            String introduce = WebUtils.paramTrim(request, "introduce", "");
            if (introduce.length() > 45){
            	AppControllerStatic.printErrorMsg(response, "车友会简介最多45个汉字", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            	return;
            }
            String appBanner = WebUtils.param(request, "appBanner", "");
            if(appBanner.length()>100){
            	AppControllerStatic.printErrorMsg(response, "非法车友会封面", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            	return;
            }
            	
            ClubDraft clubDraft = this.reqConvert2ClubDraft(request, userId);
            int result=clubDraftService.createOrUpdate(clubDraft);
            if (result <= 0) {
                AppControllerStatic.printErrorMsg(response, "创建失败", json, callback, AppControllerStatic.V1_VERSION_LATEST);
            } else {
                AppControllerStatic.printSuccessMsg(response, json, callback, AppControllerStatic.V1_VERSION_LATEST);
            }
        } catch (Exception e) {
            log.error("创建车友会草稿", e);
            AppControllerStatic.printErrorMsg(response, "创建失败，请联系管理员", json, callback, AppControllerStatic.V1_VERSION_LATEST);
        }
    }
    
    /**
     * 转换成车友会草稿对象
     *
     * @param request
     * @param userId 登录用户id
     * @return
     */
    private ClubDraft reqConvert2ClubDraft(HttpServletRequest request, long userId) {
        ClubDraft clubDraft = new ClubDraft();
        Date currentDate = DateUtils.getNow();
        //设置参数
        clubDraft.setUserId(userId);
        clubDraft.setName(WebUtils.paramTrim(request, "clubName", ""));
        clubDraft.setClubUrl(WebUtils.paramTrim(request, "clubUrl", "").replaceAll(" ", "").toLowerCase());
        clubDraft.setProvinceId(WebUtils.paramLong(request, "provinceId", 0));
        clubDraft.setProvinceName(WebUtils.paramTrim(request, "provinceName", ""));
        clubDraft.setCityId(WebUtils.paramLong(request, "cityId", 0));
        clubDraft.setCityName(WebUtils.paramTrim(request, "cityName", ""));
        clubDraft.setBrandId(WebUtils.paramLong(request, "brandId", 0));
        clubDraft.setBrandName(WebUtils.paramTrim(request, "brandName", ""));
        clubDraft.setSeriesId(WebUtils.paramLong(request, "seriesId", 0));
        clubDraft.setSeriesName(WebUtils.paramTrim(request, "seriesName", ""));
        clubDraft.setIntroduce(WebUtils.paramTrim(request, "introduce", ""));
        clubDraft.setThemeId(WebUtils.paramLong(request, "themeId", 0));
        clubDraft.setAppBanner(WebUtils.param(request, "appBanner", ""));
        clubDraft.setTypeId(WebUtils.paramInt(request, "typeId", -1));
        clubDraft.setQqGroup(WebUtils.param(request, "qqGroup", ""));
        clubDraft.setCreateBy(userId);
        clubDraft.setCreateAt(currentDate);
        return clubDraft;
    }

    /**
     * 获取创建车友会草稿信息
     *
     * @param request
     * @param response
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/getCreateClubInfo.do", method = RequestMethod.GET)
    public void getCreateClubInfo(HttpServletRequest request, HttpServletResponse response) {
        WebUtils.setEncoding4App(request, response);
        String callback = AppControllerStatic.paramCallback(request);
        int xssEncode = AppControllerStatic.paramXssEncode(request);
        JSONObject json = new JSONObject();

        User user = userAuth.getUser(request, response);
        
        if(user == null || user.getUid() <= 0) {
        	 AppControllerStatic.printErrorMsg(response, "用户未登录", json, callback, AppControllerStatic.V1_VERSION_LATEST);
             return;
        }
        
        json.put("userId", user.getUid());
        JSONObject clubDraftObject = new JSONObject();
        ClubDraft clubDraft = clubDraftService.findDraftByUserId(user.getUid());
        if (clubDraft != null) {
            clubDraftObject = xssEncode > 0 ? clubDraft.toJsonEncodeHTML() : clubDraft.toJson();
            long themeId = clubDraft.getThemeId();
            Theme theme = themeService.findThemeById(themeId);
            clubDraftObject.put("themeName", theme == null ? "" : theme.getThemeName());
            
        }
        json.put("clubInfo", clubDraftObject);
        AppControllerStatic.printSuccessMsg(response, json, callback, AppControllerStatic.V1_VERSION_LATEST);
    }

    /**
     * 根据用户ID获取已加入的车友会列表
     * @param request
     * @param response
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/getClubsByUserId.do", method = RequestMethod.GET)
    public void getClubsByUserId(HttpServletRequest request, HttpServletResponse response) {
    	WebUtils.setEncoding4App(request, response);
    	long userId = AppControllerStatic.paramUserId(request);
    	int xssEncode = AppControllerStatic.paramXssEncode(request);
    	String callback = AppControllerStatic.paramCallback(request);
    	
    	JSONObject jsonObject = new JSONObject();
    	JSONArray jsonArray = new JSONArray();
    	
    	User user = userService.findUser(userId);
    	if(user == null || user.getUid() <= 0) {
    		AppControllerStatic.printErrorMsg(response, "非法参数userId", jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
    		return;
    	}
    	
    	List<Club> clubList = clubService.listByUserId(userId);
    	for(Club club : clubList) {
    		JSONObject json = new JSONObject();
    		json.put("clubId", club.getClubId());
    		json.put("clubName", xssEncode == 0 ? 
    				club.getName() : EncodeUtils.encodeForHTMLFilterNull(club.getName()));
    		
    		jsonArray.add(json);
    	}
    	
    	jsonObject.put("userId", userId);
    	jsonObject.put("clubs", jsonArray);
    	AppControllerStatic.printSuccessMsg(response, jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
    	
    }
    
    /**
     * 根据用户ID获取已加入的车友会列表(多个用户ID）
     * @param request
     * @param response
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/getClubsByUserIds.do", method = RequestMethod.GET)
    public void getClubsByUserIds(HttpServletRequest request, HttpServletResponse response) {
    	WebUtils.setEncoding4App(request, response);
    	String[] userIds = WebUtils.param(request, "userIds", "").split(",");
    	int xssEncode = AppControllerStatic.paramXssEncode(request);
    	String callback = AppControllerStatic.paramCallback(request);
    	
    	JSONObject jsonObject = new JSONObject();
    	
    	if(userIds.length == 1 && StringUtils.isBlank(userIds[0])) {
    		AppControllerStatic.printErrorMsg(response, "非法参数userIds", jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
    		return;
    	}
    	
    	for(int i=0 ; i<userIds.length; i++) {
    		try {
    			long userId = Long.parseLong(userIds[i]);
    			User user = userService.findUser(userId);
    			if(user != null) {
    				List<Club> clubList = clubService.listByUserId(userId);
    				JSONObject json = new JSONObject();
    				for(Club club : clubList) {
    					json.put("clubId", club.getClubId());
    		    		json.put("clubName", xssEncode == 0 ? 
    		    				club.getName() : EncodeUtils.encodeForHTMLFilterNull(club.getName()));
    				}
    				
    				if(!json.isEmpty()) {
    					jsonObject.put(String.valueOf(userId), json);
    				}
    			}
    			
    		} catch (NumberFormatException exception) {

    			log.error("fail to change string {} to long", userIds[i]);
    		}
    	}
    	
    	AppControllerStatic.printSuccessMsg(response, jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
    	
    }
    
    /**
     * 获取论坛相关车友会接口
     * 旧接口：/club/listClubByForumId.do
     * @throws
     */
    @ResponseBody
    @RequestMapping(value = "/1.0/club/listClubByForumId.do", method = RequestMethod.GET)
    public void listClubByForumId(HttpServletRequest request, HttpServletResponse response) {
    	WebUtils.setEncoding4App(request, response);
        
        long forumId = WebUtils.paramLong(request, "forumId", 0);
        
        int pageNo = AppControllerStatic.paramPageNo(request);
        int pageSize = AppControllerStatic.paramPageSize(request);
        int xssEncode = AppControllerStatic.paramXssEncode(request);
        String callback = AppControllerStatic.paramCallback(request);
        
        JSONObject jsonObject = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        
        if(forumId == 0) {
        	AppControllerStatic.printErrorMsg(response, "非法参数forumId", jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
        }
        
        Pager<Club> pager = clubService.pagerClubByForumId(forumId, pageNo, pageSize);
        if (pager != null && !pager.getResultList().isEmpty()) {
            for (Club club : pager.getResultList()) {
            	JSONObject json = new JSONObject();
                json.put("clubId", club.getClubId());
                json.put("memberNum", club.getMemberNum());
                json.put("level", club.getLevelId());
                if (xssEncode > 0) {
                    json.put("name", EncodeUtils.encodeForHTMLFilterNull(club.getName()));
                    json.put("logo", EncodeUtils.encodeForHTMLFilterNull(club.getLogo()));
                    json.put("seriesName", EncodeUtils.encodeForHTMLFilterNull(club.getSeriesName()));
                } else {
                    json.put("name", club.getName());
                    json.put("logo", club.getLogo());
                    json.put("seriesName", club.getSeriesName());
                }

                jsonArray.add(json);
            }
        } 
        
        jsonObject.put("clubList", jsonArray);
        AppControllerStatic.printSuccessMsgPager(response, jsonObject, callback, pager, AppControllerStatic.V1_VERSION_LATEST);
    }
    
    /**
     * 提交入会申请
     *
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/1.0/club/applyJoinClub.do", method = RequestMethod.POST)
    @ResponseBody
    public void applyJoinCLub(HttpServletRequest request, HttpServletResponse response) throws IOException {
        WebUtils.setEncoding(request, response);
        long clubId = AppControllerStatic.paramClubId(request);
        String callback = AppControllerStatic.paramCallback(request);
        
        JSONObject jsonObject =new JSONObject();
        
        if (clubId <= 0) {
            AppControllerStatic.printErrorMsg(response, "车友会不存在", jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        
        //判断是否符合申请条件
        String result = applyMembership(clubId, request, response);
        if (StringUtils.isNotBlank(result)) {
        	AppControllerStatic.printErrorMsg(response, result, jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        
        AppControllerStatic.printSuccessMsg(response, "申请成功，申请结果将以系统短消息的形式通知，请注意查收", jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
    }
    
    /**
     * 车友会pv接口
     * 
     * @param req
     * @param resp
     */
    @RequestMapping(value = "/1.0/club/addVisitorPv.do", method = RequestMethod.POST)
    @ResponseBody
    public void addPv(HttpServletRequest req, HttpServletResponse resp) {
    	WebUtils.setEncoding4App(req, resp);
    	long clubId = AppControllerStatic.paramClubId(req);
        String callback = AppControllerStatic.paramCallback(req);
        
        Club club = clubService.getValidClub(clubId);
        if (club != null) {
            clubPvService.savePv(club.getClubId(),DateUtils.getTodayYmd());
            AppControllerStatic.printSuccessMsg(resp, "创建成功", null, callback, AppControllerStatic.V1_VERSION_LATEST);
        } else {
        	AppControllerStatic.printErrorMsg(resp, "clubId参数有误", null, callback,  AppControllerStatic.V1_VERSION_LATEST);
        }
    }

    /**
     * 判断是否符合申请条件，返回空串表示操作成功
     * @param clubId
     * @param request
     * @param response
     * @return
     */
    private String applyMembership(long clubId, HttpServletRequest request, HttpServletResponse response) {
        User user = userAuth.getUser(request, response);
        if (user.getUid() <= 0) {
            return "没有登录";
        }
        
        String phone = WebUtils.paramTrim(request, "phone", "");
    	String realName = WebUtils.paramTrim(request, "realName", user.getUsername());
    	int gender = WebUtils.paramInt(request, "gender", 0);
    	long cityId = WebUtils.paramLong(request, "cityId", 0);
    	long provinceId = WebUtils.paramLong(request, "provinceId", 0);
    	String cityName = WebUtils.getAreaPlaceByReq(request, "cityName", "");
    	String provinceName = WebUtils.paramTrim(request, "provinceName", "");
    	String brand = WebUtils.paramTrim(request, "brand", "");
        String serial = WebUtils.paramTrim(request, "serial", "");
        String brandName = WebUtils.getAreaPlaceByReq(request, "brandName", "").trim();
        int serialId = WebUtils.paramInt(request, "serial", 0);
        
        //判断是否已经申请别的车友会了
        List<MemberApplication> apps = memberService.findMemberApplication(user.getUid(), 0l, true);
        if(!apps.isEmpty()) {
        	return "您已经申请加入了车友会，请等候审核";
        }
        
        if (!user.isComplete() || StringUtils.isBlank(user.getCarInfo())) {
            int DB_MAX_LENGTH = 255;

            if (StringUtils.isNotEmpty(phone) && !phone.matches(Regex.cellphone.value)) {
                return "请输入正确的手机号码";
            }
            user.setPhone(phone);

            
            if (StringUtils.isBlank(realName) || realName.length() > DB_MAX_LENGTH) {
                return "请输入合法的姓名";
            }
            user.setTruename(realName);

            user.setGender(gender);

            if (StringUtils.isNotEmpty(provinceName) && provinceName.length() > DB_MAX_LENGTH) {
                return "非法的省份名称";
            }
            user.setProvince(provinceName);

            if (StringUtils.isNotEmpty(cityName) && cityName.length() > DB_MAX_LENGTH) {
                return "非法的城市名称";
            }
            user.setCity(cityName);
           
            if (StringUtils.isNotBlank(brandName)) {
                brandName = brandName.substring(2, brandName.length());
            }
            String serialName = WebUtils.paramTrim(request, "serialName", "");
            String carInfo = "";
            if (!brand.isEmpty() && !brand.equals("0") && !brandName.isEmpty()) {
                carInfo += brand + ";" + brandName + ";";
            }
            if (!serial.isEmpty() && !serial.equals("0") && !serialName.isEmpty()) {
                carInfo += serial + ";" + serialName + ";";
            }
            if (carInfo.endsWith(";")) {
                carInfo = carInfo.substring(0, carInfo.length() - 1);
            }
            if (carInfo.length() > DB_MAX_LENGTH) {
                return "非法的爱车信息";
            }
            user.setCarInfo(carInfo);
            userService.updateUser(user);

        }
        if (!memberService.findMemberApplication(user.getUid(), clubId, true).isEmpty()) {
            return "您已经申请加入了该车友会，请等候审核。";
        }
        if (!memberService.listClubMemberByUser(user.getUid()).isEmpty() || !clubService.findByFounder(user.getUid(), true).isEmpty()) { //已经申请加入另一个车友会 或 已创建一个车友会待审核
            return "您只能申请或加入一个车友会";
        }
        if (memberService.countByclubIdUid(clubId, user.getUid()) != null) {
            return "您已经加入了该车友会。";
        }
        int joinClubLimit = NumberUtils.toInt(systemConfig.getJoinClubLimit());
        int count = userService.updateJoinedClubCount(user);
        if (count >= joinClubLimit) {
            return "您已经加入了其他车友会，无法申请。";
        }
        Club club = clubService.getValidClub(clubId);
        if (club == null) {
            return "车友会已经被锁定";
        }
        memberService.applyMembership(user, club);//创建入会申请

        String clubUrl = clubService.getClubIndexUrl(club.getClubId(), club.getClubUrl());
        String msg1 = messageService.assembleClubUrl(club.getClubUrl(), club.getName());
        String msg2 = String.format("<a href=\"%s\" target=\"_blank\">%s</a>", clubUrl + "member/", "会员列表");

        //通知车友会管理员去审核
        List<ClubMember> admins = memberService.listAdmins(clubId);
        for (ClubMember m : admins) {
            messageService.send(userService.findUser(m.getUid()), MessageService.APPLY_RECEIVED, msg1, user.getNickname(), msg2);
        }
        //同步车系车型
        if (serialId > 0) {
            intfService.checkBrandSerial(WebUtils.paramInt(request, "brand", 0),
                    serialId,
                    systemConfig.getUserSessionName(),
                    WebUtils.cookie(request, systemConfig.getUserSessionName()));
        }
        //同步个人资料
        updateUserCenter(request, gender, realName, phone, provinceId, cityId);
        return "";
    }
    
    /**
     * 同步个人资料到个人中心
     * @param params
     * @return
     */
    private String updateUserCenter(HttpServletRequest request, int gender, String realName, String phone, long provinceId, long cityId) {
        String commonSessionId = cn.pconline.passport2.util.WebUtils.getCookie(request, systemConfig.getUserSessionName());
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("realName", realName);
        params.put("gender", gender==0 ? MALE: FEMALE);//车友会（0：男，1:女），个人中心（1：男，2：女）
        params.put("telephone", phone);
        /*
        params.put("postCode", clubAddress.getPostcode());
        params.put("address", clubAddress.getAddress());
        */
        //省市同步，只传 cityId即可，如果没有cityId,传provinceId; 如果都没有，不同步
        long domicileId = 0;
        if(cityId != 0) {
        	domicileId = cityId;
        } else if(provinceId != 0) {
        	domicileId = provinceId;
        }
        if(domicileId > 0) {
        	params.put("domicileId", domicileId);//城市ID
        }
        
        params.put("act", "save");
        params.put(systemConfig.getUserSessionName(), commonSessionId);
        String ucRoot = systemConfig.getUcRoot();
        String result = simpleHttpTemplate.post(ucRoot + "/intf/club/updateUser.jsp", null, new ResponseExtractor<String>() {
            @Override
            public String extractData(HttpResponse response) throws IOException {
                StatusLine statusLine = response.getStatusLine();
                if (statusLine.getStatusCode() == 200) {
                    try {
                        return EntityUtils.toString(response.getEntity());
                    } catch (IOException ex) {
                        log.error("sendToMyCenter fail 1!", ex);
                    } catch (ParseException ex) {
                        log.error("sendToMyCenter fail 2!", ex);
                    }
                } else {
                    log.error("sendToMyCenter fail statusCode is " + statusLine.getStatusCode());
                    try {
                        log.error(EntityUtils.toString(response.getEntity()));
                    } catch (IOException ex) {
                        log.error("sendToMyCenter fail--IOException", ex);
                    } catch (ParseException ex) {
                        log.error("sendToMyCenter fail--ParseException", ex);
                    }
                }
                return "";
            }
        }, EntityBuilder.entity().params(params).build());
       
        return result;
    }
    
    
    @ResponseBody
    @RequestMapping(value = "/1.0/club/todayCheckInList.do", method = RequestMethod.GET)
    public void todayCheckInList(HttpServletRequest request, HttpServletResponse response) throws IOException {
        WebUtils.setEncoding4App(request, response);
        long clubId = AppControllerStatic.paramClubId(request);
        int pageNo = AppControllerStatic.paramPageNo(request);
        int pageSize = AppControllerStatic.paramPageSize(request);
        String callback = AppControllerStatic.paramCallback(request);
        
        JSONObject jsonObject =new JSONObject();
        JSONArray jsonArray = new JSONArray();
        
        Club club = clubService.getValidClub(clubId);
        if(club == null) {
        	AppControllerStatic.printErrorMsg(response, "车友会不存在", jsonObject, callback, AppControllerStatic.V1_VERSION_LATEST);
            return;
        }
        
        Pager<CheckIn> pager = checkInService.pagerForClubId(clubId, pageNo, pageSize);
        if(pager != null && !pager.getResultList().isEmpty()) {
        	User user;
        	for(CheckIn checkIn : pager.getResultList()) {
        		JSONObject json = new JSONObject();
        		long userId = checkIn.getUid();
        		json.put("userId", userId);
        		user = userService.findUser(userId);
        		json.put("nickName", user == null ? "" : user.getNickname());
        		json.put("checkInTime", checkIn.getLastCheckInAt());
        		jsonArray.add(json);
        	}
        }
        
        jsonObject.put("checkInList", jsonArray);
        
        AppControllerStatic.printSuccessMsgPager(response, jsonObject, callback, pager, AppControllerStatic.V1_VERSION_LATEST);
    }
    
}
